package tt.dz.common;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.PrintStream;
import java.io.Reader;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

public class CSVReadUtils
{
  private static volatile CSVReadUtils instance;
  
  public static CSVReadUtils getInstance()
  {
    if (instance == null) {
      synchronized (CSVReadUtils.class)
      {
        instance = new CSVReadUtils();
      }
    }
    return instance;
  }
  
  public static <T> List<T> readExistsHeaderCsvToObjectList(Reader reader, String[] headers, Class<T> clazz)
    throws Exception
  {
    return readExistsHeaderCsvToObjectList(reader, Arrays.asList(headers), clazz);
  }
  
  public static <T> List<T> readExistsHeaderCsvToObjectList(Reader reader, List<String> headers, Class<T> clazz)
    throws Exception
  {
    return readCsvToObjectList(reader, headers, Boolean.valueOf(true), clazz);
  }
  
  public static <T> List<T> readCsvToObjectList(Reader reader, List<String> headers, Boolean isExistsHeader, Class<T> clazz)
    throws Exception
  {
//    CSVReadUtils tmp11_8 = getInstance();tmp11_8.getClass();
//    ObjectCsvImportRowHander csvImportRowHander=new ObjectCsvImportRowHander();
    return null;
  }
  
  public static <T> List<T> readCsv(Reader reader, List<String> headers, Boolean isExistsHeader, Class<T> clazz, CsvImportRowHander<T> csvImportRowHander, CsvCellFormatHander cellFormatHander)
    throws Exception
  {
    List<T> result = new ArrayList();
    isExistsHeader = Boolean.valueOf(isExistsHeader != null ? isExistsHeader.booleanValue() : true);
    boolean isContinneHeader = !isExistsHeader.booleanValue();
    int headerSize = headers.size();
    CSVParser csvFileParser = null;
    CSVFormat csvFileFormat = CSVFormat.DEFAULT.withHeader((String[])headers.toArray(new String[0]));
    csvFileParser = new CSVParser(reader, csvFileFormat);
    List<CSVRecord> csvRecords = csvFileParser.getRecords();
    for (CSVRecord csvRecord : csvRecords) {
      if (csvRecord.size() >= headerSize) {
        if (!isContinneHeader)
        {
          isContinneHeader = true;
        }
        else
        {
          csvImportRowHander.setClazz(clazz);
          T instance = csvImportRowHander.hander(csvRecord, headers, cellFormatHander);
          if (instance != null) {
            result.add(instance);
          }
        }
      }
    }
    csvFileParser.close();
    return result;
  }
  
  public class ObjectCsvImportRowHander<T>
    implements CSVReadUtils.CsvImportRowHander<T>
  {
    private Class<T> clazz;
    
    public ObjectCsvImportRowHander() {}
    
    public T hander(CSVRecord csvRecord, List<String> headers, CSVReadUtils.CsvCellFormatHander cellFormatHander)
      throws Exception
    {
      T instance = null;
      instance = this.clazz.newInstance();
      for (String header : headers)
      {
        PropertyDescriptor propertyDesc = null;
        try
        {
          propertyDesc = new PropertyDescriptor(header, this.clazz);
        }
        catch (IntrospectionException e) {
        	 continue;
        }
       
        
        String valueString = csvRecord.get(header);
        valueString = valueString != null ? valueString.trim() : null;
        if ((valueString != null) && (!"".equals(valueString)))
        {
          if (cellFormatHander != null) {
            valueString = cellFormatHander.format(header, valueString);
          }
          Class<?> propertyType = propertyDesc.getPropertyType();
          Method writeMethod = propertyDesc.getWriteMethod();
          if (propertyType == Date.class)
          {
            String _formatter = null;
            if (valueString.trim().length() == 10) {
              _formatter = "yyyy-MM-dd";
            }
            if (valueString.trim().length() > 10) {
              _formatter = "yyyy-MM-dd HH:mm:ss";
            }
            if (_formatter != null) {
              try
              {
                SimpleDateFormat sdf = new SimpleDateFormat(_formatter);
                writeMethod.invoke(instance, new Object[] { sdf.parse(valueString) });
              }
              catch (ParseException localParseException) {}
            }
          }
          if (propertyType == BigDecimal.class) {
            try
            {
              BigDecimal valeBigDecimal = new BigDecimal(valueString);
              writeMethod.invoke(instance, new Object[] { valeBigDecimal });
            }
            catch (NumberFormatException e)
            {
              System.out.println(header + ":" + valueString);
            }
          }
          if (propertyType == Integer.class) {
            try
            {
              writeMethod.invoke(instance, new Object[] { Integer.valueOf(valueString) });
            }
            catch (NumberFormatException localNumberFormatException1) {}
          }
          if (propertyType == Double.class) {
            try
            {
              writeMethod.invoke(instance, new Object[] { Double.valueOf(valueString) });
            }
            catch (NumberFormatException localNumberFormatException2) {}
          }
          if (propertyType == String.class) {
            writeMethod.invoke(instance, new Object[] { valueString });
          }
        }
      }
      return instance;
    }
    
    public void setClazz(Class<T> clazz)
    {
      this.clazz = clazz;
    }
  }
  
  public static abstract interface CsvImportRowHander<T>
  {
    public abstract T hander(CSVRecord paramCSVRecord, List<String> paramList, CSVReadUtils.CsvCellFormatHander paramCsvCellFormatHander)
      throws Exception;
    
    public abstract void setClazz(Class<T> paramClass);
  }
  
  public static abstract interface CsvCellFormatHander
  {
    public abstract String format(String paramString1, String paramString2);
  }
}
